package compiler.nonterminals;

import howl.types.TableDescriptor;
import howl.types.Unit;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import compiler.HowlToken;
import compiler.HowlType;
import compiler.TokenReader;
import compiler.exceptions.HowlParserException;
import compiler.terminals.DataDecl;
import compiler.terminals.FeedName;

/**
 * This class represents create statements, as in:
 * 
 * create FeedName DataProvider (Name Unit)+
 * 
 * @author Sarah Mount <s.mount@wlv.ac.uk>
 * @version 16 Dec 2009
 * @see compiler.terminals.FeedName
 * @see compiler.terminals.DataDecl
 */
public class CreateStmt extends HowlToken {

	private FeedName feedname;
	private List<DataDecl> declarations;

	public CreateStmt(TokenReader tokenReader) {
		super(tokenReader);
	}

	@Override
	public String codeGenerate() {
		String declarations = "";
		// TODO: Use iterators sensibly here.
		Object[] declArray = this.declarations.toArray();
		for (int i = 0; i < declArray.length - 1; i++) {
			declarations += ((DataDecl) declArray[i]).codeGenerate() + ", ";
		}
		// No comma after last declaration.
		declarations += ((DataDecl) declArray[declArray.length - 1])
				.codeGenerate();
		return "CREATE " + this.feedname.codeGenerate() + " (" + declarations
				+ ");";
	}

	@Override
	public HowlToken parse() throws HowlParserException {
		String command = this.tokenReader.consumeToken();
		if (!"create".equals(command))
			throw new HowlParserException(this.tokenReader.getStatement(),
					this.tokenReader.getCharNo());
		this.feedname = (FeedName) new FeedName(this.tokenReader).parse();
		this.declarations = new LinkedList<DataDecl>();
		while (!this.tokenReader.hasEndStmt()) {
			DataDecl decl = (DataDecl) new DataDecl(this.tokenReader).parse();
			this.declarations.add(decl);
		}
		return this;
	}

	@Override
	public String toString() {
		String obj = "";
		obj += "create ";
		obj += this.feedname.toString();
		for (DataDecl decl : this.declarations) {
			obj += " " + decl.toString();
		}
		return obj + ";";
	}

	/**
	 * @return the feedname
	 */
	public FeedName getFeedname() {
		return feedname;
	}

	/**
	 * @param feedname the feedname to set
	 */
	public void setFeedname(FeedName feedname) {
		this.feedname = feedname;
	}

	/**
	 * @return the declarations
	 */
	public List<DataDecl> getDeclarations() {
		return declarations;
	}

	/**
	 * @param declarations the declarations to set
	 */
	public void setDeclarations(List<DataDecl> declarations) {
		this.declarations = declarations;
	}

}